package com.ybkj.o2o.sales.common.page.impl;


import com.ybkj.o2o.sales.common.page.Page;
import com.ybkj.o2o.sales.common.page.Pageable;

import java.util.List;

public class PageImpl<T> extends Chunk<T> implements Page<T> {

  private static final long serialVersionUID = 867755909294344406L;

  private final long total;

  /**
   * Constructor of {@code PageImpl}.
   * 
   * @param content the content of this page, must not be {@literal null}.
   * @param pageable the paging information, can be {@literal null}.
   * @param total the total amount of items available
   */
  public PageImpl(List<T> content, Pageable pageable, long total) {

    super(content, pageable);
    this.total = total;
  }

  /**
   * Creates a new {@link PageImpl} with the given content. This will result in the created
   * {@link Page} being identical to the entire {@link List}.
   * 
   * @param content must not be {@literal null}.
   */
  public PageImpl(List<T> content) {
    this(content, null, null == content ? 0 : content.size());
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.ybkj.daijia.page.Page#getTotalPages()
   */
  @Override
  public int getTotalPages() {
    return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize());
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.ybkj.daijia.page.Page#getTotalElements()
   */
  @Override
  public long getTotalElements() {
    return total;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.springframework.data.domain.Slice#hasNext()
   */
  @Override
  public boolean hasNext() {
    return getNumber() + 1 < getTotalPages();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.springframework.data.domain.Slice#isLast()
   */
  @Override
  public boolean isLast() {
    return !hasNext();
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {

    String contentType = "UNKNOWN";
    List<T> content = getContent();

    if (content.size() > 0) {
      contentType = content.get(0).getClass().getName();
    }

    return String.format("Page %s of %d containing %s instances", getNumber(), getTotalPages(),
        contentType);
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {

    if (this == obj) {
      return true;
    }

    if (!(obj instanceof PageImpl<?>)) {
      return false;
    }

    PageImpl<?> that = (PageImpl<?>) obj;

    return this.total == that.total && super.equals(obj);
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {

    int result = 17;

    result += 31 * (int) (total ^ total >>> 32);
    result += 31 * super.hashCode();

    return result;
  }

}
